const socketIO = require('socket.io');
const jwt = require('jsonwebtoken');
const { secret } = require('../config/jwtConfig');
const UserModel = require('../models/userModel');
const MessageModel = require('../models/messageModel');
const visitorManager = require('../utils/visitorManager');
const GroupController = require('../controllers/groupController');
const cookieConfig = require('../config/cookie');
const groupManager = require('../utils/groupManager');

// 存储用户连接
const userSockets = new Map(); // email -> socket

function initializeSocket(server) {
    console.log('初始化Socket.IO服务器...');

    const io = socketIO(server, {
        cors: {
            origin: function (origin, callback) {
                console.log('收到连接请求，来源:', origin);
                if (!origin) {
                    return callback(null, true);
                }
                callback(null, origin);
            },
            credentials: true,
            methods: ["GET", "POST"]
        },
        pingTimeout: 60000,
        pingInterval: 25000
    });

    // 身份验证中间件
    io.use(async (socket, next) => {
        try {
            console.log('验证socket连接...');
            const token = socket.handshake.auth.token;
            if (!token) {
                console.log('未提供token');
                return next(new Error('Authentication error'));
            }

            const decoded = jwt.verify(token, secret);
            console.log('token验证成功，用户:', decoded.id || decoded.name);

            // 检查是否是游客
            if (decoded.isVisitor) {
                const existingUser = await UserModel.findByName(decoded.name);
                if (existingUser) {
                    return next(new Error('Name is already registered'));
                }
                visitorManager.addVisitor(decoded.name, decoded, socket.id);
                socket.user = decoded;
            } else {
                const user = await UserModel.findById(decoded.id);
                if (!user) {
                    return next(new Error('User not found'));
                }
                socket.user = user;
            }

            next();
        } catch (error) {
            console.error('socket验证失败:', error.message);
            next(new Error('Authentication error'));
        }
    });

    io.on('connection', (socket) => {
        console.log('新用户连接:', socket.id, '用户:', socket.user?.name || socket.user?.id);

        // 存储用户连接
        if (!socket.user.isVisitor) {
            userSockets.set(socket.user.email, socket);
            console.log('已注册用户连接:', socket.user.email);
        }

        // 广播在线但未加入群聊的用户列表给所有用户
        io.emit('group:online_users_not_in_groups', {
            users: groupManager.getOnlineUsersNotInGroups(io)
        });

        // 添加cookie事件处理
        socket.on('cookie:get', () => {
            console.log('收到cookie:get请求，来自socket:', socket.id, '用户:', socket.user?.name || socket.user?.id);
            try {
                socket.emit('cookie:update', {
                    status: 'success',
                    data: {
                        cookie: cookieConfig.cookie
                    }
                });
                console.log('已发送cookie更新');
            } catch (error) {
                console.error('发送cookie更新失败:', error);
                socket.emit('error', {
                    message: '发送cookie更新失败'
                });
            }
        });

        // 添加连接状态监听
        socket.on('disconnect', () => {
            console.log('用户断开连接:', socket.id, '用户:', socket.user?.name || socket.user?.id);

            // 在断开连接前，先退出所有聊天室并发送通知
            const groups = groupManager.getAllGroupsInfo(socket.server);
            groups.forEach(group => {
                const groupId = group.groupId;
                if (groupManager.isMember(groupId, socket.id)) {
                    // 离开群聊
                    groupManager.leaveGroup(groupId, socket.id);
                    socket.leave(groupId);

                    // 通知其他用户有成员离开
                    socket.to(groupId).emit('group:member_left', {
                        groupId: groupId,
                        user: {
                            avatar: socket.user.avatar || null,
                            name: socket.user.name,
                            email: socket.user.email || null,
                            isVisitor: socket.user.isVisitor ? true : null
                        }
                    });
                }
            });

            // 广播所有群聊信息更新
            socket.server.emit('group:all_groups', {
                groups: groupManager.getAllGroupsInfo(socket.server)
            });

            // 处理用户断开连接
            if (socket.user.isVisitor) {
                visitorManager.removeVisitorBySocketId(socket.id);
            } else {
                userSockets.delete(socket.user.email);
            }

            // 广播更新后的在线但未加入群聊的用户列表给所有用户
            socket.server.emit('group:online_users_not_in_groups', {
                users: groupManager.getOnlineUsersNotInGroups(socket.server)
            });
        });

        // 添加错误处理
        socket.on('error', (error) => {
            console.error('Socket错误:', error);
        });

        // 测试连接
        socket.emit('connection:success', {
            status: 'success',
            message: '连接成功',
            socketId: socket.id
        });

        // 发送私信
        socket.on('private_message', async (data) => {
            try {
                const { recipientEmail, message, type = 0 } = data;

                // 查找接收者
                const recipient = await UserModel.findByEmailWithPassword(recipientEmail);
                if (!recipient) {
                    socket.emit('error', {
                        message: '接收者不存在'
                    });
                    return;
                }

                // 存储消息
                const messageData = {
                    sender_id: socket.user.id,
                    recipient_id: recipient.id,
                    message,
                    type,
                    timestamp: new Date(),
                    is_read: 0
                };

                const result = await MessageModel.create(messageData);

                // 构建发送的消息对象
                const messageInfo = {
                    id: result.insertId,
                    from: {
                        id: socket.user.id,
                        email: socket.user.email,
                        name: socket.user.name,
                        avatar: socket.user.avatar
                    },
                    message,
                    type,
                    timestamp: messageData.timestamp,
                    is_read: false
                };

                // 如果接收者在线，发送消息
                const recipientSocket = userSockets.get(recipientEmail);
                if (recipientSocket) {
                    recipientSocket.emit('private_message', messageInfo);
                }

                // 发送确认消息给发送者
                socket.emit('message_sent', {
                    id: result.insertId,
                    to: recipientEmail,
                    message,
                    type,
                    timestamp: messageData.timestamp
                });

            } catch (error) {
                console.log(error)
                socket.emit('error', {
                    message: '发送消息失败'
                });
            }
        });

        // 发送私信提示
        socket.on('private_message_hint', async (data) => {
            try {
                const { recipientEmail, message, type = 0 } = data;

                // 查找接收者
                const recipient = await UserModel.findByEmailWithPassword(recipientEmail);
                if (!recipient) {
                    socket.emit('error', {
                        message: '接收者不存在'
                    });
                    return;
                }

                // 存储消息
                const messageData = {
                    sender_id: socket.user.id,
                    recipient_id: recipient.id,
                    message,
                    type,
                    timestamp: new Date(),
                };

                // 构建发送的消息对象
                const messageInfo = {
                    id: recipient.insertId,
                    from: {
                        id: socket.user.id,
                        email: socket.user.email,
                        name: socket.user.name,
                        avatar: socket.user.avatar
                    },
                    message,
                    type,
                    timestamp: messageData.timestamp,
                };

                // 如果接收者在线，发送消息
                const recipientSocket = userSockets.get(recipientEmail);
                if (recipientSocket) {
                    recipientSocket.emit('private_message_hint', messageInfo);
                }

            } catch (error) {

                socket.emit('error', {
                    message: '发送消息失败'
                });
            }
        });

        // 获取与特定用户的聊天记录
        socket.on('get_chat_history', async (data) => {

            try {
                console.log("开始获取聊天记录，参数:", data);
                const { otherUserEmail } = data;

                if (!otherUserEmail) {
                    console.error("缺少必要参数: otherUserEmail");
                    socket.emit('error', {
                        message: '缺少必要参数'
                    });
                    return;
                }

                console.log("查找用户:", otherUserEmail);
                const otherUser = await UserModel.findByEmailWithPassword(otherUserEmail);

                if (!otherUser) {
                    console.error("用户不存在:", otherUserEmail);
                    socket.emit('error', {
                        message: '用户不存在'
                    });
                    return;
                }

                const messages = await MessageModel.getMessagesBetweenUsers(
                    socket.user.id,
                    otherUser.id
                );

                socket.emit('chat_history', {
                    messages,
                    otherUser: {
                        id: otherUser.id,
                        email: otherUser.email,
                        name: otherUser.name,
                        avatar: otherUser.avatar
                    }
                });


            } catch (error) {
                console.error("获取聊天记录失败:", error);
                socket.emit('error', {
                    message: '获取聊天记录失败'
                });
            }
        });

        // 标记消息为已读
        socket.on('mark_as_read', async (data) => {
            try {
                const { senderEmail } = data;
                const sender = await UserModel.findByEmailWithPassword(senderEmail);

                if (sender) {
                    await MessageModel.markAsRead(sender.id, socket.user.id);
                    socket.emit('messages_marked_as_read', { senderEmail });
                }
            } catch (error) {
                socket.emit('error', {
                    message: '标记消息已读失败'
                });
            }
        });

        // 群聊功能
        // 加入群聊
        socket.on('group:join', (groupId) => {
            console.log('用户加入群聊:', socket.user.name, groupId);
            GroupController.joinGroup(socket, groupId);
        });

        // 发送群聊消息
        socket.on('group:message', (data) => {
            console.log('群聊消息:', socket.user.name, data.groupId, data.content);
            GroupController.sendMessage(socket, data.groupId, data.content);
        });

        // 发送群聊提示消息
        socket.on('group:hint_message', (data) => {
            console.log('群聊提示消息:', socket.user.name, data.groupId, data.content);
            GroupController.sendHintMessage(socket, data.groupId, data.content);
        });

        // 离开群聊
        socket.on('group:leave', (groupId) => {
            console.log('用户离开群聊:', socket.user.name, groupId);
            GroupController.leaveGroup(socket, groupId);
        });

        // 获取群聊成员信息
        socket.on('group:get_members', (groupId) => {
            console.log('获取群聊成员:', socket.user.name, groupId);
            GroupController.getGroupMembers(socket, groupId);
        });

        // 获取所有群聊信息
        socket.on('group:get_all_groups', () => {
            console.log('获取所有群聊信息:', socket.user.name);
            GroupController.getAllGroups(socket);
        });

        // 获取群聊播放状态
        socket.on('group:get_playback_state', (groupId) => {
            console.log('获取群聊播放状态:', socket.user.name, groupId);
            GroupController.getPlaybackState(socket, groupId);
        });

        // 获取所有群聊的播放状态
        socket.on('group:get_all_playback_states', () => {
            console.log('获取所有群聊播放状态:', socket.user.name);
            GroupController.getAllPlaybackStates(socket);
        });

        // 更新群聊播放状态
        socket.on('group:update_playback_state', (data) => {
            console.log('更新群聊播放状态:', socket.user.name, data.groupId, data.state);
            GroupController.updatePlaybackState(socket, data);
        });

        // 获取在线但未加入任何群聊的用户列表
        socket.on('group:get_online_users_not_in_groups', () => {
            console.log('获取在线但未加入群聊的用户列表:', socket.user.name);
            GroupController.getOnlineUsersNotInGroups(socket);
        });

        // 退出所有聊天室
        socket.on('group:leave_all_groups', () => {
            console.log('用户退出所有聊天室:', socket.user.name);
            GroupController.leaveAllGroups(socket);
        });
    });

    // 添加广播cookie的方法
    io.broadcastCookie = () => {
        console.log('广播cookie给所有客户端');
        io.emit('cookie:update', {
            status: 'success',
            data: {
                cookie: cookieConfig.cookie
            }
        });
    };

    console.log('Socket.IO服务器初始化完成');
    return io;
}

module.exports = initializeSocket; 